/*************************
*** File util_list.c
**************************/

#include "util_list.h"
#include <stdlib.h>
//创建链表
TSList_S *TSCreateList()
{
    TSList_S * pstList = (TSList_S*) malloc(sizeof(TSList_S));
    //初始化nNodeCount为0
    pstList->nNodeCount = 0;
    pstList->pstFirstNode = NULL;
    pstList->pstLastNode = NULL;
    pstList->TSEqual = NULL;
    return pstList;
}

//释放链表
void TSFreeList(TSList_S* pstList)
{
    TSNode_S* pstTSNodeTemp = NULL;
    TSNode_S* pstTSNodeTemp1 = NULL;

    if(NULL == pstList)
    {
        return;
    }

    if(NULL == pstList->pstFirstNode || NULL == pstList->pstLastNode)
    {
        //链表里面没有任何节点
        free(pstList);
        pstList = NULL;
        return;
    }

    pstTSNodeTemp = pstList->pstFirstNode;
    while (NULL != pstTSNodeTemp)
    {
        pstTSNodeTemp1 = pstTSNodeTemp->pstNext;
        //释放节点里面具体数据内存的回调
        pstList->TSFreeNode(pstTSNodeTemp->TSData);
        pstTSNodeTemp->TSData = NULL;
        //释放节点
        free(pstTSNodeTemp);
        pstTSNodeTemp = NULL;
        pstTSNodeTemp = pstTSNodeTemp1;
    }

    //释放链表本体
    free(pstList);

    pstList = NULL;
    return;
}


/*
pmt_free(void* TSData)
{
	 Pmt_str str = (Pmt_str*)TSData;
	 	{
	 	free(str.ccc)
		free(str);
	 }
}

TSList_S s;
s->TSFreeNode = pmt_free;
*/

//插入在尾部
void TSListInsertDataTail(TSList_S* pstTSList, void* pstTSData)
{
    TSNode_S* pstTSNode = (TSNode_S*)malloc(sizeof(TSNode_S));
    pstTSNode->TSData = pstTSData;
    pstTSNode->pstNext = NULL;

    //list里面已经有了至少一个节点
    if ( 0 < pstTSList->nNodeCount)
    {
        //将新的节点挂载到last后面
        pstTSList->pstLastNode->pstNext = pstTSNode;
        //将last指向刚最新挂载的节点上
        pstTSList->pstLastNode = pstTSNode;
    }
    else
    {
        pstTSList->pstFirstNode = pstTSNode;
        pstTSList->pstLastNode = pstTSNode;
    }
    (pstTSList->nNodeCount) ++;
}

//插入在首部
void TSListInsertDataHead(TSList_S* pstTSList, void* pstTSData)
{
    TSNode_S* pstTSNode = (TSNode_S*)malloc(sizeof(TSNode_S));
    pstTSNode->TSData = pstTSData;
    pstTSNode->pstNext = NULL;

    //list里面已经有了至少一个节点
    if (0 < pstTSList->nNodeCount)
    {
        pstTSNode->pstNext = pstTSList->pstFirstNode;
        pstTSList->pstFirstNode = pstTSNode;
    }
    else
    {
        //将新的节点挂载到first之前
        pstTSList->pstFirstNode = pstTSNode;
        pstTSList->pstLastNode = pstTSNode;
    }
    (pstTSList->nNodeCount) ++;
}

//长度
int TSListGetSize(TSList_S* pstTSList)
{
    return pstTSList->nNodeCount;
}

//打印 -- 需要调用方 提供具体每一个节点的打印函数
void TSListPrint(TSList_S* pstTSList, void(*TSDataPrint)(void *TSData))
{
    TSNode_S* pstTSNodeTemp = pstTSList->pstFirstNode;
    while (pstTSNodeTemp)
    {
        //回调每一个节点的具体打印函数
        (*TSDataPrint)(pstTSNodeTemp->TSData);
        pstTSNodeTemp = pstTSNodeTemp->pstNext;
    }
}


//删除在尾部
void* TSListRemoveDataTail(TSList_S* pstTSList)
{
    TSNode_S* pstTSNodeTemp = pstTSList->pstFirstNode;
    void* retTSData = NULL;
    int i = 0;

    while(NULL != pstTSNodeTemp)
    {
        if ( 1 == pstTSList->nNodeCount)
        {
            return TSListRemoveDataHead(pstTSList);
        }

        if(pstTSNodeTemp->pstNext != NULL && pstTSNodeTemp->pstNext != pstTSList->pstLastNode)
        {
            pstTSNodeTemp = pstTSNodeTemp->pstNext;
            continue;
        }

        //移动尾部指针
        pstTSList->pstLastNode = pstTSNodeTemp;
        //将节点里面保存的 数据对象 返回
        retTSData = pstTSNodeTemp->pstNext->TSData;
        //释放节点
        free(pstTSNodeTemp->pstNext);

        pstTSNodeTemp->pstNext = NULL;

        //链表节点个数 减一
        pstTSList->nNodeCount --;

        return retTSData;
    }
}

//删除在首部
void* TSListRemoveDataHead(TSList_S* pstTSList)
{
    TSNode_S* pstTSNodeTemp = pstTSList->pstFirstNode;
    void* retTSData = NULL;
    pstTSList->pstFirstNode = pstTSNodeTemp->pstNext;
    retTSData = pstTSNodeTemp->TSData;

    free(pstTSNodeTemp);

    (pstTSList->nNodeCount) --;
    if (0 == pstTSList->nNodeCount)
    {
        pstTSList->pstLastNode = NULL;
    }

    return retTSData;
}

//插入  -- nIndex 下标从0开始
void TSListInsertData(TSList_S* pstTSList, void* pstTSData, int nIndex)
{

    TSNode_S* pstTSNode = (TSNode_S*)malloc(sizeof(TSNode_S));
    TSNode_S* pstTSNodeTemp = NULL;
    int i = 0;

    //下标为 0 相当于从头插入
    if (nIndex == 0)
    {
        TSListInsertDataHead(pstTSList, pstTSData);
        return;
    }

    //下标为 当前链表节点个数时。从尾部插入
    if (nIndex == pstTSList->nNodeCount)
    {
        TSListInsertDataTail(pstTSList, pstTSData);
        return;
    }

    pstTSNode->TSData = pstTSData;
    pstTSNode->pstNext = NULL;

    pstTSNodeTemp = pstTSList->pstFirstNode;
    for (i = 0; i < nIndex - 1; i++)
    {
        pstTSNodeTemp = pstTSNodeTemp->pstNext;
    }

    //插入操作
    //将要插入的节点 的next 指向后一个[前一个的next]
    pstTSNode->pstNext = pstTSNodeTemp->pstNext;
    //将前一个的 next 指向当前节点
    pstTSNodeTemp->pstNext = pstTSNode;

    (pstTSList->nNodeCount) ++;

    return;
}


//删除
void* TSListRemoveData(TSList_S* pstTSList, int nIndex)
{
    TSNode_S* pstTSNodeTemp = NULL;
    TSNode_S* pstTSNodeTemp1 = NULL;
    void* retTSNode = NULL;
    int i = 0;

    if (0 == nIndex)
    {
        return TSListRemoveDataHead(pstTSList);
    }

    if (nIndex == pstTSList->nNodeCount - 1)
    {
        return TSListRemoveDataTail(pstTSList);
    }

    pstTSNodeTemp = pstTSList->pstFirstNode;
    for (i = 0; i < nIndex - 1; i++)
    {
        pstTSNodeTemp = pstTSNodeTemp->pstNext;
    }

    pstTSNodeTemp1 = pstTSNodeTemp->pstNext;
    pstTSNodeTemp->pstNext = pstTSNodeTemp->pstNext->pstNext;
    retTSNode = pstTSNodeTemp1->TSData;

    free(pstTSNodeTemp1);
    pstTSNodeTemp1 = NULL;

    (pstTSList->nNodeCount) --;

    return retTSNode;
}

//取得数据
void* TSListGetData(TSList_S* pstTSList, int nIndex)
{
    TSNode_S* pstTSNodeTemp = NULL;
    int i = 0;

    if(nIndex >= pstTSList->nNodeCount)
    {
        return NULL;
    }

    if(0 == nIndex)
    {
        TSListGetDataHead(pstTSList);
    }

    if (nIndex == pstTSList->nNodeCount - 1)
    {
        return TSListGetDataTail(pstTSList);
    }

    pstTSNodeTemp = pstTSList->pstFirstNode;
    for (i = 0; i < nIndex; i++)
    {
        pstTSNodeTemp = pstTSNodeTemp->pstNext;
    }
    return pstTSNodeTemp->TSData;
}

//取得第一个数据
void* TSListGetDataHead(TSList_S* pstTSList)
{
    return pstTSList->pstFirstNode->TSData;
}

//取得最后一个数据
void* TSListGetDataTail(TSList_S* pstTSList)
{
    return pstTSList->pstLastNode->TSData;
}

/*
//查找某个数据的位置,如果equal方法为空，比较地址，否则调用equal方法
//如果不存在返回-1，如果存在，返回出现的第一个位置
int myListFindDataIndex(const MyList * const list, void * data)
{
    MyNode * p = list->first;
    int re = 0;
    if (list->equal)
    {
        while (p)
        {
            if (p->data == data || (*(list->equal))(p->data, data))
            {
                return re;
            }
            re++;
            p = p->next;
        }

    }
    else
    {
        while (p)
        {
            if (p->data == data)
            {
                return re;
            }
            re++;
            p = p->next;
        }
    }
    return -1;
}
*/

/*
//创建链表，带有相等参数，用于查找
MyList * createMySearchList(int(*equal)(void * a, void * b))
{
    MyList * re = createMyList();
    re->equal = equal;
    return re;
}
*/

//创建遍历器
TSListIterator_S* TSCreateListIterator(TSList_S*          pstTSList)
{
    TSListIterator_S* pstTSListIterator = (TSListIterator_S*) malloc(sizeof(TSListIterator_S));
    pstTSListIterator->p = pstTSList->pstFirstNode;
    pstTSListIterator->allSize = pstTSList->nNodeCount;
    pstTSListIterator->count = 0;
    return pstTSListIterator;
}

//释放遍历器
void TSFreeListIterator(TSListIterator_S* pstIterator)
{
    //其内部结构不能释放
    free(pstIterator);
}

//遍历器是否有下一个元素
int TSListIteratorHasNext(TSListIterator_S* pstIterator)
{
    //判断 是否当前 遍历的位置 到了最后的位置[最后的位置 = allSize-1]所以是小于号
    return pstIterator->count < pstIterator->allSize;
}

//返回遍历器的下一个元素
void * TSListIteratorNext(TSListIterator_S* pstIterator)
{
    void* retTSNode = pstIterator->p->TSData;
    pstIterator->p = pstIterator->p->pstNext;
    (pstIterator->count) ++;
    return retTSNode;
}

/*
//删除对象,返回是否删除成功
int TSListRemoveData(MyList* const list, void * data)
{
    MyListIterator * it = createMyListIterator(list);
    int a = 0;
    while (myListIteratorHasNext(it))
    {
        void * ld = myListIteratorNext(it);
        if (data == ld || (list->equal != NULL && (*(list->equal))(ld, data)))
        {
            a = 1;
            break;
        }
    }
    if (a)
    {
        myListRemoveDataAt(list, it->count - 1);
    }
    return a;
}
*/

typedef struct A
{
    int cccc;
}A;


void free_a(void* data)
{
    printf("----%#x----\n", data);
    free(data);
    data = NULL;
}

int main()
{
    TSList_S* list = TSCreateList();
    A* a = (A*)malloc(sizeof(A));
    A* a1 = (A*)malloc(sizeof(A));
    A* a2 = (A*)malloc(sizeof(A));
    //A* a3 = a;

    TSListIterator_S* s;
    TSListIterator_S* s1;
    int result = 0;
    A* temp;
    list->TSFreeNode = free_a;

    a->cccc = 1;
    a1->cccc = 2;
    a2->cccc = 3;
    TSListInsertDataTail(list, a);
    TSListInsertDataTail(list, a1);
    TSListInsertDataTail(list, a2);

    s = TSCreateListIterator(list);

    while(1)
    {
        result = TSListIteratorHasNext(s);
        if(result)
        {
            temp = (A*)TSListIteratorNext(s);
            printf("----%#x----\n", temp);
        }
        else
        {
            break;
        }
    }

    TSFreeList(list);
    //free(a);
    //a->cccc = 10;

    //printf("----%#x----\n", a->cccc);
    if(NULL == a && NULL == a1 && NULL == a2)
    {
        printf("\n----good----\n");
    }
    /*
    printf("-------------------------------------\n");
    TSListRemoveData(list, 1);
    s1 = TSCreateListIterator(list);
    while(1)
    {
        result = TSListIteratorHasNext(s1);
        if(result)
        {
            temp = (A*)TSListIteratorNext(s1);
            printf("----%d----\n", temp->cccc);
        }
        else
        {
            break;
        }
    }
    */


}

